/*
    Author: Christopher Diggins
    License: MIT Licence 1.0
    Website: http://www.heron-language.com
*/

#ifndef LLSCHEME_LEVEL1_HPP
#define LLSCHEME_LEVEL1_HPP

namespace lls
{		
	struct Final : SExpr {
		Final(ConstString s) {
			AddChild(new Name(s));
		}
		Final() { }
		String Label() { return "final"; }
		SExpr* NewInstance() { return new Final(); }		
		Name* GetNameExpr() { return children[0]->As<Name>(); }
		String GetNameStr() { return GetNameExpr()->Label(); } 
	};

	struct Undeclare : SExpr {
		Undeclare(ConstString s) {
			AddChild(new Name(s));
		}
		Undeclare() { }
		String Label() { return "undeclare"; }
		SExpr* NewInstance() { return new Undeclare(); }		
		Name* GetNameExpr() { return children[0]->As<Name>(); }
		String GetNameStr() { return GetNameExpr()->Label(); } 
	};


	struct Pop : SExpr {
		String Label() { return "pop"; }
		SExpr* NewInstance() { return new Pop(); }		
		SExpr* Expr() { return children[0]; }
	};

	struct Internal : SExpr {
		String Label() { return "_internal_"; }
		SExpr* NewInstance() { return new Internal(); }		
	};

	struct DigN : PSExpr<int> {
		DigN(int n, ConstString s) 
			: PSExpr<int>(n, s) 
		{ }
		String Label() { return "digN"; }
		SExpr* NewInstance() { return new DigN(Param(), Name()); }
	};

	struct GetN : PSExpr<int> {
		GetN(int n, ConstString s) 
			: PSExpr<int>(n, s) 
		{ }
		String Label() { return "getN"; }
		SExpr* NewInstance() { return new GetN(Param(), Name()); }
	};

	struct SetN : PSExpr<int> {
		SetN(int n, ConstString s) 
			: PSExpr<int>(n, s) 
		{ }
		String Label() { return "setN"; }
		SExpr* NewInstance() { return new SetN(Param(), Name()); }
	};

	struct ZapN : PSExpr<int> {
		ZapN(int n, ConstString s) 
			: PSExpr<int>(n, s) 
		{ }
		String Label() { return "zapN"; }
		SExpr* NewInstance() { return new ZapN(Param(), Name()); }
	};

	struct GetF : PSExpr<int> {
		GetF(int n, ConstString s) 
			: PSExpr<int>(n, s)
		{ }
		String Label() { return "getF"; }
		SExpr* NewInstance() { return new GetF(Param(), Name()); }
	};

	struct External : SExpr {
		External()
		{ }
		External(ConstString s) 
		{ 
			AddChild(new Name(s));
		}
		String Label() { return "external"; }
		Name* GetNameExpr() { return children[0]->As<Name>(); }
		String GetNameStr() { return GetNameExpr()->Label(); } 
		SExpr* NewInstance() { return new External(); } 
	};

	bool IsMatchingUndeclare(SExpr* x, ConstString s) {
		return DoesNameMatch<Undeclare>(x, s);
	}
}

#endif
